package com.mls.fivedistrict.mq;


import com.github.pagehelper.util.StringUtil;
import com.mls.fivedistrict.common.GDResponse;
import com.mls.fivedistrict.common.ServiceResponse;
import com.mls.fivedistrict.enums.RecordStatusEnum;
import com.mls.fivedistrict.enums.ResponseCode;
import com.mls.fivedistrict.enums.WithdrawStatusEnum;
import com.mls.fivedistrict.exception.CustomerException;
import com.mls.fivedistrict.pojo.ExtractEntity;
import com.mls.fivedistrict.pojo.Record;
import com.mls.fivedistrict.pojo.WithdrawRecord;
import com.mls.fivedistrict.server.PropertyService;
import com.mls.fivedistrict.server.RecordService;
import com.mls.fivedistrict.server.SysSettingService;
import com.mls.fivedistrict.server.WithdrawRecordService;
import com.mls.fivedistrict.util.JsonUtils;
import com.mls.fivedistrict.util.Md5Utils;
import com.mls.fivedistrict.util.RsaUtils;
import com.mls.fivedistrict.util.jedis.RedisPoolUtil;
import com.rabbitmq.client.Channel;
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.core.ChannelAwareMessageListener;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.security.PublicKey;
import java.util.HashMap;
import java.util.Map;

import static java.math.BigDecimal.ROUND_DOWN;

/**
 * Created by chenxiuxiang on 2018/5/5.
 */
@Slf4j
public class WithdrawCustomer implements ChannelAwareMessageListener {
    @Resource(name = "recordService")
    RecordService recordService;
    @Resource(name = "propertyService")
    PropertyService propertyService;

    @Resource(name = "sysSettingService")
    SysSettingService sysSettingService;

    @Resource(name = "withdrawRecordService")
    WithdrawRecordService withdrawRecordService;
    int sum = 0;

    @Transactional
    @Override
    public void onMessage(Message message, Channel channel) throws Exception {
        ExtractEntity extractEntity = null;
        try {
            log.info("sum{}", sum++);
            String json = new String(message.getBody(), "utf-8");
            if (!StringUtil.isEmpty(json)) {
                extractEntity = JsonUtils.jsonToPojo(json, ExtractEntity.class);
                WithdrawRecord detail = withdrawRecordService.getDetail(extractEntity.getWithdrawRecordId());
                if (detail == null) {
                    WithdrawRecord withdrawRecord = new WithdrawRecord();
                    withdrawRecord.setId(extractEntity.getWithdrawRecordId());
                    withdrawRecord.setFailCause("WithdrawRecordDetail为空");
                    int i2 = withdrawRecordService.updateWithdrawValue(withdrawRecord);
                    if (i2 <= 0) {
                        throw new Exception("detail为空标记失败");
                    }
                }
                if (detail != null && !detail.getStatus().equals(WithdrawStatusEnum.SUBMITTED.getValue())) {
                    throw new Exception("状态不一致:" + detail.getStatus());
                }
                BigDecimal value = extractEntity.getValue();
//                log.info("value{}", value);
                if (extractEntity.getServiceCharge() > 0) {
                    value = value.multiply(new BigDecimal(1 - extractEntity.getServiceCharge())).setScale(4, ROUND_DOWN);
                }
                GDResponse gdResponse = extractGD(extractEntity.getUserId(), extractEntity.getgUserId(), value + "", extractEntity.getgIntegralId(), "127.0.0.1");
                if (gdResponse.getStatus() != 1) {
                    //1.资产还回去
                    int row = propertyService.increatementPropertyTotal(extractEntity.getUserId(), extractEntity.getIntegralId(), extractEntity.getValue());
                    if (row <= 0) {
                        throw new Exception();
                    }
                    //2.添加记录
                    Record record = new Record();
                    record.setStatus(RecordStatusEnum.ALREADYRECEIVE.getValue());
                    record.setChangeReason("提现失败");
                    record.setValue(extractEntity.getValue());
                    record.setSource("提现失败");
                    record.setIntergralId(extractEntity.getIntegralId());
                    record.setUserId(extractEntity.getUserId());
                    int i1 = recordService.insertRecord(record);
                    if (i1 <= 0) {
                        throw new Exception();
                    }
                    Record successRecord = new Record();
                    successRecord.setId(extractEntity.getRecordId());
                    successRecord.setSource("资产提取(失败)");
                    successRecord.setChangeReason("资产提取(失败)");
                    recordService.editRecord(successRecord);
                    //3.提现记录标记失败
                    Map map = new HashMap();
                    map.put("id", extractEntity.getWithdrawRecordId());
                    map.put("status", WithdrawStatusEnum.FAIL.getValue());
                    map.put("sourceStatus", WithdrawStatusEnum.SUBMITTED.getValue());
                    map.put("failCause", gdResponse.getInfo());
                    int i2 = withdrawRecordService.updateWithdrawStatus(map);
                    if (i2 <= 0) {
                        throw new Exception("提现记录标记失败");
                    }
                } else {
                    BigDecimal serviceChargeTotal = new BigDecimal(0);
                    //1.扣除手续费 统一添加到官方账号
                    double serviceCharge = extractEntity.getServiceCharge();
                    if (serviceCharge > 0) {
                        //手续费>0
                        String officialAccount = RedisPoolUtil.get("officialAccount");
                        if (StringUtil.isEmpty(officialAccount)) {
                            ServiceResponse sysSettings = sysSettingService.getSysSettings();
                            if (sysSettings.getState().equals(ResponseCode.SUCCESS.getCode())) {
                                officialAccount = (String) ((Map) sysSettings.getData()).get("officialAccount");
                                if (!StringUtil.isEmpty(officialAccount)) {
                                    RedisPoolUtil.set("officialAccount", officialAccount);
                                }
                            }
                        }
                        if (StringUtil.isEmpty(officialAccount)) {
                            officialAccount = "27";
                            RedisPoolUtil.set("officialAccount", officialAccount);
                        }
                        log.info("官方账号:{}", officialAccount);
                        //1.1将资产转入官方账号同时添加记录
                        log.info("{},{}", extractEntity.getValue(), value);
                        serviceChargeTotal = extractEntity.getValue().subtract(value).setScale(4, ROUND_DOWN);
                        log.info("手续费:{}", serviceChargeTotal);
                        int i1 = propertyService.increatementPropertyTotal(Long.valueOf(officialAccount), extractEntity.getIntegralId(), serviceChargeTotal);
                        if (i1 <= 0) {
                            throw new Exception("增加手续费资产错误");
                        }
                        //1.2添加记录
                        Record record = new Record();
                        record.setUserId(Long.valueOf(officialAccount));
                        record.setValue(serviceChargeTotal);
                        record.setSource(extractEntity.getPhone() + "提现手续费");
                        record.setChangeReason(extractEntity.getPhone() + "提现手续费");
                        record.setStatus(RecordStatusEnum.ALREADYRECEIVE.getValue());
                        record.setIntergralId(extractEntity.getIntegralId());
                        int i3 = recordService.insertRecord(record);
                        if (i3 <= 0) {
                            throw new Exception("增加手续费记录错误");
                        }
                    }
                    Record successRecord = new Record();
                    successRecord.setId(extractEntity.getRecordId());
                    successRecord.setSource("资产提取(已成功)");
                    successRecord.setChangeReason("资产提取(已成功)");
                    recordService.editRecord(successRecord);
                    //2.提现记录标记成功
                    WithdrawRecord withdrawRecord = new WithdrawRecord();
                    withdrawRecord.setWithdrawValue(value);
                    withdrawRecord.setId(extractEntity.getWithdrawRecordId());
                    withdrawRecord.setStatus(WithdrawStatusEnum.SUCCEED.getValue());
                    withdrawRecord.setServiceChargeTotal(serviceChargeTotal);
                    int i2 = withdrawRecordService.updateWithdrawValue(withdrawRecord);
                    if (i2 <= 0) {
                        throw new Exception("提现记录标记成功错误");
                    }

                }
            }
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("执行出错{}", e.getMessage());
            if (extractEntity != null) {
                WithdrawRecord withdrawRecord = new WithdrawRecord();
                withdrawRecord.setId(extractEntity.getWithdrawRecordId());
                withdrawRecord.setFailCause(e.getMessage());
                int i2 = withdrawRecordService.updateWithdrawValue(withdrawRecord);
                if (i2 <= 0) {
                    throw new Exception("提现记录标记失败原因");
                }
            }

            channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, false);
        }
    }

    /**
     * 调用国盾接口提现
     *
     * @param userId
     * @param gUserId
     * @param value
     * @param integral
     * @param ip       @return
     */
    private GDResponse extractGD(Long userId, Long gUserId, String value, Long integral, String ip) {
//        if (true) {
//            try {
//                Thread.sleep(1000);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//            GDResponse gdResponse1 = new GDResponse();
//            gdResponse1.setStatus(1);
//            return gdResponse1;
//        }

//        log.info("提现金额:{},积分ID{}", value, integral);

        String publick =
                "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMcfCZAT8Z4wjxGIgfezfCE0zZ\n" +
                        "aG+L8sDLfljGTosJv0+L+9h9hY/B9c+y3IEv4OmXg+eClkHimNLWYR7h6HODsSJg\n" +
                        "yiJwyUPXJzdqUeju2vuTFErhob0qPsMxoyLdi8+7Nbk5Km65xwCwbRBoIEJD7u9a\n" +
                        "d5rwVZX0obG9ySOPyQIDAQAB\n";
        String signParams = "DWQ=DWQ&D_USER_ID=" + userId + "&G_C_ID=" + integral + "&G_USER_ID=" + gUserId + "&IP=" + ip + "&TRS_CNT=" + value;

//        System.out.println("signParams:" + signParams);
        signParams = Md5Utils.encryptPassword(signParams, "");
        PublicKey publicKey = RsaUtils.generatePublicKey(publick);
        byte[] bytes;
        try {
            bytes = RsaUtils.encryptData((signParams.getBytes("GBK")), publicKey);
        } catch (Exception e) {
            e.printStackTrace();
            throw new CustomerException("加密出错");
        }
//        System.out.println(Base64.encode(bytes));

        String url = "https://www.guodunc.com/Api/Five/addcoin";
        RestTemplate client = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        //  请勿轻易改变此提交方式，大部分的情况下，提交方式都是表单提交
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        //  封装参数，千万不要替换为Map与HashMap，否则参数无法传递
        MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
        //  也支持中文
        params.add("D_USER_ID", userId + "");
        params.add("G_USER_ID", gUserId + "");
        params.add("G_C_ID", integral + "");
        params.add("TRS_CNT", value);
        params.add("DWQ", "DWQ");
        params.add("rsakey", Base64.encode(bytes));
        params.add("IP", ip);
        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(params, headers);//将参数和header组成一个请求
        ResponseEntity<String> response = client.postForEntity(url, request, String.class);
//        log.info("body:" + response.getBody());
        if (response.getStatusCode().value() == 200) {
            //代表成功
            String body = response.getBody();
            GDResponse gdResponse = JsonUtils.jsonToPojo(body, GDResponse.class);
//            log.info("info:{}", gdResponse.getInfo());
            return gdResponse;
//            if (gdResponse.getStatus() == 1) {
//                return 1;
//            } else {
//                failCause = gdResponse.getInfo();
//                return -1;
//            }
        }
        return null;
    }

}
